/**  
 * All rights Reserved, Designed By www.tydic.com
 * @Title:  MyJob.java   
 * @Package com.axin.job   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: axin     
 * @date:   2019年3月8日 下午11:32:30   
 * @version V1.0 
 * @Copyright: 2019 www.hao456.top Inc. All rights reserved. 
 */
package com.axin.job;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.PersistJobDataAfterExecution;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.axin.common.entity.ApiToken;
import com.axin.common.entity.response.BalanceBean;
import com.axin.common.entity.response.Merged;
import com.axin.common.entity.response.OrdersDetail;
import com.axin.common.exception.ApiException;
import com.axin.common.exception.TaskRuntimeException;
import com.axin.common.exception.TaskStartException;
import com.axin.common.quartz.QuartzManager;
import com.axin.common.utils.JobUtil;
import com.axin.entity.HbTask;
import com.axin.entity.HbTrades;
import com.axin.entity.bo.BuyResult;
import com.axin.service.AccountService;
import com.axin.service.CommonService;
import com.axin.service.MarketService;
import com.axin.service.MessageService;
import com.axin.service.OrderService;
import com.axin.service.TaskService;
import com.axin.service.TradesService;


/**
 * 反弹百分比按购买线的价格计算
 * @Description: TODO 
 * @ClassName:  ATacticsJob
 * @author:  Axin 
 * @date:   2019年6月12日 下午9:41:11   
 * @Copyright: 2019 www.hao456.top Inc. All rights reserved.
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class JobA implements Job{
 
    private Logger logger = LoggerFactory.getLogger(JobA.class);
 
    //直接注入  
    @Autowired
    private CommonService commonService;
    @Autowired
    private QuartzManager quartzManager;
    @Autowired
    private MessageService messageService;
    @Autowired
    private MarketService marketService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private TradesService tradesService;
    
    //基础参数
    Long userId;
    ApiToken token;
    
    String symbol;//监控的交易对
    int buyTradeCount;
    int buyTradeLimit;
    String firstMoney;
    
   //买入参数               
    String buyLevel;
    String buyMethod;
    String reboundPercent;//反弹百分比
    String minPrice;//最低价
    boolean downing;//下跌中
    
    String buyBasePrice; //保存第一单成交时的均价，用来计算下单位置    
    
    
    //卖出参数                
    String profitPercent;//止盈百分点
    String fallBackPercent;//回落百分比
    String maxPrice;//最高价
    boolean uping;//上涨中
    
    
    int loopCount;
    String totalAmount;
    String totalMoney; 
    		                     
    Integer accountId; 
    int moneyScale;
    int amountScale;
    String quoteCurrency;
    
    Long taskId;//任务id
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
	     //String string = dateTime.toString("yyyy-MM-dd hh:mm:ss");
	     JobDataMap dataMap = context.getJobDetail().getJobDataMap();
	     
	     //基础参数
	     this.userId = dataMap.getLong("userId");
	     this.token = (ApiToken)dataMap.get("token");
	     
	     this.symbol = dataMap.getString("symbol");//监控的交易对
	     this.buyTradeCount= dataMap.getInt("buyTradeCount");
	     this.buyTradeLimit= dataMap.getInt("buyTradeLimit");
	     this.firstMoney = dataMap.getString("firstMoney");
	     
	     //买入参数
	     this.buyLevel = dataMap.getString("buyLevel");
	     this.buyMethod = dataMap.getString("buyMethod");
	     this.reboundPercent = dataMap.getString("reboundPercent");//反弹百分比
	     this.minPrice = dataMap.getString("minPrice");//最低价
	     this.downing = dataMap.getBoolean("downing");//下跌中
	     
	     this.buyBasePrice = dataMap.getString("buyBasePrice");//保存第一单成交时的均价，用来计算下单位置
	     
	     //卖出参数
	     this.profitPercent = dataMap.getString("profitPercent");//止盈百分点
	     this.fallBackPercent = dataMap.getString("reboundPercent");//回落百分比
	     this.maxPrice = dataMap.getString("maxPrice");//最高价
	     this.uping = dataMap.getBoolean("uping");//上涨中
	     
	     this.loopCount = dataMap.getInt("loopCount");
	     this.totalAmount = dataMap.getString("totalAmount");
	     this.totalMoney = dataMap.getString("totalMoney");
	     
	     this.accountId = dataMap.getInt("accountId");
	     this.moneyScale = dataMap.getInt("moneyScale");
	     this.amountScale = dataMap.getInt("amountScale");
	     this.quoteCurrency = dataMap.getString("quoteCurrency");
	    
	     JobKey jobKey = context.getJobDetail().getKey();
		 TriggerKey triggerKey = context.getTrigger().getKey();
		 this.taskId = Long.valueOf(jobKey.getName());
	    
  		try {
  			if(buyTradeCount == 0){//本轮第一单
  				//计算账户资金是否足够
  				send(userId, "系统正在初始化新一轮交易");
  				BalanceBean balance = this.accountService.getBalanceByAccountId(token, accountId, AccountService.BALANCE_TYPE_TRADE, quoteCurrency);
  				BigDecimal balanceBig = new BigDecimal(balance.getBalance()).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
  				send(userId, "获取"+quoteCurrency+"账户余额: " + balanceBig.toPlainString());
  				send(userId, "根据策略计算账户余额是否足够本轮交易");
  				//获取策略
  				String[] strs = JobUtil.getStrategyMoney(firstMoney, buyTradeLimit, moneyScale,buyMethod);
  				BigDecimal total = new BigDecimal(firstMoney);
  				for (String str : strs) {
  					total = total.add(new BigDecimal(str));
  				}
  				//根据首单金额和策略判断账户资金是否足够
  				if(balanceBig.compareTo(total) < 0){
  					BigDecimal diff = total.subtract(balanceBig).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
  					send(userId, "【账户信息】"+quoteCurrency+"账户余额不足，差额"+diff.toPlainString()+"，请保证账户内余额大于或等于 " +total.toPlainString());
  					send(userId, "任务终止");
  					//结束任务
  					
  					System.out.println(jobKey.getName()+","+jobKey.getGroup()+","+triggerKey.getName()+","+triggerKey.getGroup());
  					quartzManager.removeJob(jobKey.getName(), jobKey.getGroup(), triggerKey.getName(), triggerKey.getGroup());
  					
  					HbTask task = new HbTask(taskId,"0");
  					this.taskService.updateTaskById(task, userId);
  					throw new TaskStartException();
  				}
  				
  				send(userId, "【账户信息】账户余额充足");
  				
  				//以当前市价购买第一单
  				BigDecimal firstMoneyBig = new BigDecimal(firstMoney).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
  				send(userId, "以当前市场价格买进第一单，金额:" + firstMoneyBig.toPlainString());
  				BuyResult buyResult = this.orderService.createBuyOrderWithDetail(token, symbol, accountId, firstMoney, moneyScale, amountScale);
  				String state = buyResult.getState();
  				if("filled".equals(state) || "partial-filled".equals(state)){
  					BigDecimal totalAmountBig = new BigDecimal(StringUtils.isEmpty(totalAmount) ? "0.00" : totalAmount);
  					BigDecimal totalMoneyBig = new BigDecimal(StringUtils.isEmpty(totalMoney)? "0.00" : totalMoney);
  					BigDecimal fieldAmountBig = new BigDecimal(buyResult.getFieldAmount()).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
  					BigDecimal fieldMoneybig = new BigDecimal(buyResult.getFieldMoney()).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
  					if("filled".equals(state)){
  						fieldMoneybig = firstMoneyBig;
  					}
  					totalAmountBig = totalAmountBig.add(fieldAmountBig).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
  					totalMoneyBig = totalMoneyBig.add(fieldMoneybig).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
  					//减去手续费
  					BigDecimal fieldFeesBig = new BigDecimal(buyResult.getFieldFees()).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
  					totalAmountBig = totalAmountBig.subtract(fieldFeesBig).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
  					
  					totalAmount = totalAmountBig.toPlainString();
  					totalMoney = totalMoneyBig.toPlainString();
  					//计算成交均价
  					BigDecimal averageBig = totalMoneyBig.divide(totalAmountBig,moneyScale,BigDecimal.ROUND_HALF_UP);
  					buyBasePrice =  averageBig.toPlainString();
  					if("partial-filled".equals(state)){
  						send(userId, "【部分成交】交易数量： "+fieldAmountBig.toPlainString() +"，交易金额： "+fieldMoneybig.toPlainString());
  						send(userId, "撤消未完成的订单");
  						orderService.submitcancel(token, buyResult.getOrderId());
  					}else{
  						send(userId, "【买进成功】交易数量： "+fieldAmountBig.toPlainString() +"，交易金额： "+fieldMoneybig.toPlainString());
  					}
  					send(userId, "【仓位祥情】持仓数量： "+ totalAmount + "，持仓金额： "+totalMoney + "，持仓均价： "+averageBig.toPlainString());
  					buyTradeCount ++;
  					loopCount ++;
  				    //更新数据库
  					HbTask task = new HbTask(taskId, buyTradeCount, buyBasePrice, loopCount, totalAmount, totalMoney);
  					this.taskService.updateTaskById(task, userId);
  					
  					//添加交易记录表
  					HbTrades trades = new HbTrades(taskId, symbol, loopCount,"1", "1", fieldMoneybig.toPlainString(), fieldAmountBig.toPlainString(), buyBasePrice, fieldFeesBig.toPlainString(), buyResult.getCreatedAt());
  					this.tradesService.saveTrades(trades, userId);
  				}else{
  					send(userId, "【买进失败】撤消订单，重新下单");
					orderService.submitcancel(token, buyResult.getOrderId());
  				}
  			}else{
  				//获取系统时间戳
  				Merged merged = this.marketService.getDetailMerged(token, symbol);
  				BigDecimal price = new BigDecimal(merged.getClose()).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
  				
  				BigDecimal totalAmountBig = new BigDecimal(totalAmount == null ? "0.00" : totalAmount);//持仓数量
				BigDecimal totalMoneyBig = new BigDecimal(totalMoney == null ? "0.00" : totalMoney);//持仓金额
				BigDecimal averagePriceBig = totalMoneyBig.divide(totalAmountBig,moneyScale,BigDecimal.ROUND_HALF_UP);
				
				//if(false){//跌
  				if(price.compareTo(averagePriceBig) < 0){//跌
  					
  					uping = false;//将上涨的状态置为false
  					maxPrice = "0";
  					
  					BigDecimal diff = averagePriceBig.subtract(price).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
  					BigDecimal downPercent = diff.divide(averagePriceBig,5,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);
  					if(buyTradeCount < buyTradeLimit){
  						String[] positions = JobUtil.getPositions(buyBasePrice, buyLevel, buyTradeLimit, moneyScale);
  						String linePrice = positions[buyTradeCount];//购买线
  						BigDecimal linePriceBig = new BigDecimal(linePrice);
  						
  						
  						
  						if(downing){//如果此时价格是连续下跌中，则监控价格是否反弹或下跌，根据参数设置买进
  							send(userId,"<span style='color:#03CB90'>"
  								    + "【实时价格】 "+symbol + "： "+price.toPlainString()+"，"
  								    + " 持仓成本单价： "+averagePriceBig.toPlainString()+ "， ↓"+diff.toPlainString()+","
  									+ " 跌幅:"+downPercent.toPlainString()+"%"
  									+ "</span>");
  							BigDecimal minPriceBig = new BigDecimal(minPrice);
  						   //如果此次价格，比上次的价格更低，将此次价格置为最低价格
  							if(price.compareTo(minPriceBig) < 0){
  								send(userId,"价格下跌，已突破系统记录的最低价格["+minPriceBig.toPlainString()+"]，系统将更新最低价格为["+price.toPlainString()+"]");
  	  							minPrice = price.toPlainString();
  	  						}else{
  	  							//如果此次价格高于上次价，则比较是否达到反弹百分比位置，如果达到则下单补仓
  	  							
  	  							//使用成本价和回落百分比计算回落下单位置
  	  							BigDecimal reboundPercentBig = new BigDecimal(reboundPercent);
  	  							reboundPercentBig = reboundPercentBig.divide(new BigDecimal("100"),5,BigDecimal.ROUND_HALF_UP);
  	  							BigDecimal subPriceBig = minPriceBig.multiply(reboundPercentBig).setScale(moneyScale, BigDecimal.ROUND_DOWN);
  	  							//最低价加上反弹数，判断是否下单
  	  							BigDecimal positionBig = minPriceBig.add(subPriceBig).setScale(moneyScale, BigDecimal.ROUND_DOWN);
  	  							//如果此时价格<=下单位置，则下单卖出
  	  							if(price.compareTo(positionBig) >= 0){
  	  								send(userId,"价格反弹，达到反弹百分比，系统即将执行第"+(buyTradeCount+1)+"单买进动作");
  	  								buy(totalMoneyBig, totalAmountBig, averagePriceBig);//购买
  	  							}else{
  	  								send(userId,"价格反弹，暂未达到反弹百分比，继续监控...");
  	  							}
  	  						}
  							
  							
  						}else{
  							send(userId,"<span style='color:#03CB90'>"
  								    + "【实时价格】 "+symbol + "： "+price.toPlainString()+"，"
  								    + " 正在监控本轮第"+(buyTradeCount+1)+"次下单价格:"+linePriceBig.toPlainString()+"，"
  								    + " 持仓成本单价： "+averagePriceBig.toPlainString()+ "， ↓"+diff.toPlainString()+"，"
  									+ " 跌幅:"+downPercent.toPlainString()+"%"
  									+ "</span>");
  							if(price.compareTo(linePriceBig) <= 0){
  	  							
  	  							if(StringUtils.isEmpty(reboundPercent)){
  	  								reboundPercent = "0.00";
  	  	  						}
  	  	  						//如果未设置反弹百分比，则直接购买
  	  	  						BigDecimal reboundPercentBig = new BigDecimal(reboundPercent);
  	  	  						if(reboundPercentBig.doubleValue() == 0){
  	  	  							send(userId,"价格达到第"+(buyTradeCount+1)+"次买进价格，系统即将执行买进动作");
  	  	  							buy(totalMoneyBig, totalAmountBig, averagePriceBig);
  	  	  						}else{//否则，将状态改为价格置为正在上涨 uping = true
  	  	  							send(userId,"价格达到第"+(buyTradeCount+1)+"次买进价格，您设置了反弹百分比，系统将记录本次价格["+price.toPlainString()+"]为最低价格。当价格反弹并达到您设置的反弹百分比后再执行买进动作");
  	  	  							downing = true;
  	  	  							//记录此时的价格
  	  	  							minPrice = price.toPlainString();
  	  	  						}
  	  							
  	  						}
  						}
  						
  					}else{
  						send(userId,"购买次数超限。");
  						send(userId,"<span style='color:#03CB90'>【实时价格】 "+symbol + "： "+price.toPlainString()+"， 持仓价： "+averagePriceBig.toPlainString()+ "， -"+diff.toPlainString()+", 跌幅:"+downPercent.toPlainString()+"%</span>");
  					}
  					
  				}else{//涨价
  					downing = false;//将下跌的状态置为false
  					minPrice = "0";
  					BigDecimal diff = price.subtract(averagePriceBig).setScale(moneyScale, BigDecimal.ROUND_DOWN);
  					BigDecimal upPercent = diff.divide(averagePriceBig,5,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);
  					send(userId,"<span style='color:#FA4848'>【实时价格】 "+symbol + "： "+price.toPlainString()+"，"
  							+ " 持仓成本单价： "+averagePriceBig.toPlainString()+ "，"
  							+ " ↑"+diff.toPlainString()+","
  							+ " 涨幅:"+upPercent.toPlainString()+"%</span>");
  					
  					BigDecimal profit = new BigDecimal(profitPercent).setScale(2, BigDecimal.ROUND_HALF_UP);
  					
  					
  					if(uping){//如果此时价格是一直连续上涨中，则监控价格是否回落或上涨，根据参数设置卖出
  						BigDecimal maxPriceBig = new BigDecimal(maxPrice);
  						//如果此次价格，比上次的价格高，将此次价格置为最高价格
  						if(price.compareTo(maxPriceBig) > 0){
  							send(userId,"价格上涨，已突破系统记录的最高价格["+maxPriceBig.toPlainString()+"]，系统将更新最高价格为["+price.toPlainString()+"]");
  							maxPrice = price.toPlainString();
  						}else{
  							//如果此次价格低，则比较是否达到回落百分比，如果达到则下单卖出
  							//使用成本价和回落百分比计算回落下单位置
  							BigDecimal fallBackPercentBig = new BigDecimal(fallBackPercent);
  							fallBackPercentBig = fallBackPercentBig.divide(new BigDecimal("100"),5,BigDecimal.ROUND_HALF_UP);
  							BigDecimal subPriceBig = averagePriceBig.multiply(fallBackPercentBig).setScale(moneyScale, BigDecimal.ROUND_DOWN);
  							//最高价减去回落数，得出下单位置
  							BigDecimal positionBig = maxPriceBig.subtract(subPriceBig).setScale(moneyScale, BigDecimal.ROUND_DOWN);
  							//如果此时价格<=下单位置，则下单卖出
  							if(price.compareTo(positionBig)<=0){
  								send(userId,"价格回落，达到回落百分比，系统即将执行卖出动作");
  								sell(totalMoneyBig, totalAmountBig, averagePriceBig);//卖出
  							}else{
  								send(userId,"价格回落，暂未达到回落百分比，继续监控...");
  							}
  						}
  					}else{
  						//if(true){//达到卖出要求
  	  					if(upPercent.compareTo(profit) >= 0){
  	  						if(StringUtils.isEmpty(fallBackPercent)){
  	  							fallBackPercent = "0.00";
  	  						}
  	  						//如果未设置回落百分比，则直接卖出
  	  						BigDecimal fallBackPercentBig = new BigDecimal(fallBackPercent);
  	  						if(fallBackPercentBig.doubleValue() == 0){
  	  							send(userId,"预期盈利达到止盈百分比，系统即将执行卖出动作");
  	  							sell(totalMoneyBig, totalAmountBig, averagePriceBig);//卖出
  	  						}else{//否则，将状态改为价格置为正在上涨 uping = true
  	  							send(userId,"预期盈利达到止盈百分比，您设置了回落百分比，系统将记录本次价格["+price.toPlainString()+"]为最高价格。当价格回落并达到您设置的回落百分比后再执行卖出动作");
  	  							uping = true;
  	  							//记录此时的价格
  	  							maxPrice = price.toPlainString();
  	  						}
  	  						
  	  						
  	  					}
  					}
  					
  				}
  				
  			}
  			
	      	
  		//基础参数
	     dataMap.put("userId",userId);
	     dataMap.put("token",token);
	     
	     dataMap.put("symbol", symbol);
	     dataMap.put("buyTradeCount", buyTradeCount);
	     dataMap.put("buyTradeLimit", buyTradeLimit);
	     dataMap.put("firstMoney", firstMoney);
	     
	     dataMap.put("buyLevel", buyLevel);
	     dataMap.put("buyMethod", buyMethod);
	     dataMap.put("reboundPercent", reboundPercent);//反弹百分比
	     dataMap.put("minPrice", minPrice);//最低价
	     dataMap.put("minPrice", minPrice);//最低价
	     dataMap.put("downing", downing);
	     
	     dataMap.put("buyBasePrice",buyBasePrice);//保存第一单成交时的均价，用来计算下单位置
	     
	     dataMap.put("profitPercent", profitPercent);
	     dataMap.put("reboundPercent", fallBackPercent);//回落百分比
	     dataMap.put("maxPrice", maxPrice);//最高价
	     dataMap.put("uping", uping);
	     
	     dataMap.put("loopCount", loopCount);
	     dataMap.put("totalAmount", totalAmount);
	     dataMap.put("totalMoney", totalMoney);
	     
	     dataMap.put("accountId", accountId);
	     dataMap.put("moneyScale", moneyScale);
	     dataMap.put("amountScale", amountScale);
	     dataMap.put("quoteCurrency", quoteCurrency);
	     
		} catch (TaskRuntimeException e) {
			e.printStackTrace();
		} catch (TaskStartException e) {
			e.printStackTrace();
		} catch (ApiException e) {
			String errCode = e.getErrCode();
			e.printStackTrace();
			send(userId, "接口请求异常，错误码："+errCode + ",错误消息："+e.getMessage());
		}  catch (IOException e) {
			e.printStackTrace();
			send(userId, "接口请求异常，错误消息："+e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			quartzManager.removeJob(jobKey.getName(), jobKey.getGroup(), triggerKey.getName(), triggerKey.getGroup());
			send(userId, "发生系统级别异常,任务意外终止");
			HbTask task = new HbTask(taskId,"0");
			this.taskService.updateTaskById(task, userId);
			
		}
    }
    
    
    
    private void sell(BigDecimal totalMoneyBig,BigDecimal totalAmountBig,BigDecimal averagePriceBig){
    	//达到卖出要求
			//以市价卖出
			 Long orderId = this.orderService.createSellOrder(token, symbol, accountId, totalAmount);//卖出仓位所有币
			try {
				Thread.sleep(3000);//延迟3秒查询订单
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			OrdersDetail ordersDetail = this.orderService.ordersDetail(token, orderId);
			String state = ordersDetail.getState();
			if("filled".equals(state)){
				BigDecimal fieldAmountBig = new BigDecimal(ordersDetail.getFieldAmount()).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
				BigDecimal fieldMoneyBig = new BigDecimal(ordersDetail.getFieldCashAmount()).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
				//计算成交均价
				BigDecimal ave = fieldMoneyBig.divide(fieldAmountBig,moneyScale,BigDecimal.ROUND_HALF_UP);
				//计算实际收益率
				BigDecimal di = fieldMoneyBig.subtract(totalMoneyBig).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
				BigDecimal diPercent = di.divide(totalMoneyBig,5,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);
				
				send(userId, "【卖出成功】 成交数量："+fieldAmountBig.toPlainString()+"， 成交金额："+fieldMoneyBig.toPlainString()+"， 成交单价："+ave.toPlainString()+"， 本轮收益金额："+di.toPlainString()+"，  实际收益率："+diPercent.toPlainString()+"%， ");
				send(userId, "系统将更新策略参数，并开始新一轮交易");
				//初始化配置金额等参数
				buyTradeCount = 0;
				totalAmount = "0.00";
				totalMoney = "0.00";
				buyBasePrice = "0.00";
				uping = false;
				downing = false;
				maxPrice = "0.00";
				minPrice = "0.00";
				//持久化到数据库 
				HbTask task = new HbTask(taskId, buyTradeCount, totalAmount, totalMoney);
				this.taskService.updateTaskById(task, userId);
				
				//添加交易记录表
				long createTime = ordersDetail.getCreatedAt();
				Date date = new Date(createTime);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				HbTrades trades = new HbTrades(taskId, symbol, loopCount,"1", "2", fieldAmountBig.toPlainString(), fieldMoneyBig.toPlainString(), ave.toPlainString(), ordersDetail.getFieldFees(), sdf.format(date));
				this.tradesService.saveTrades(trades, userId);
			}else if("partial-filled".equals(state)){
				//获取完成的数量 在持有数量中减去
				//获取完成的金额 在持有金额中减去
				//重新计算均价，进行下一次比价
				
				BigDecimal fieldAmountBig = new BigDecimal(ordersDetail.getFieldAmount()).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
				BigDecimal fieldMoneyBig = new BigDecimal(ordersDetail.getFieldCashAmount()).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
				totalAmountBig = totalAmountBig.subtract(fieldAmountBig).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
				totalMoneyBig = totalMoneyBig.subtract(fieldMoneyBig).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
				totalAmount = totalAmountBig.toPlainString();
				totalMoney = totalMoneyBig.toPlainString();
				//计算此时的持仓均价
				averagePriceBig = totalMoneyBig.divide(totalAmountBig,moneyScale,BigDecimal.ROUND_HALF_UP);
				
				//计算成交均价
				BigDecimal ave = fieldMoneyBig.divide(fieldAmountBig,moneyScale,BigDecimal.ROUND_HALF_UP);
			
				send(userId, "【部分卖出】 成交数量："+fieldAmountBig.toPlainString()+"， 成交金额："+fieldMoneyBig.toPlainString()+"， 成交单价："+ave.toPlainString());
				send(userId, "【部分卖出】撤消未完成订单，重新比价");
				orderService.submitcancel(token, orderId);
				send(userId, "【仓位祥情】持仓数量： "+ totalAmount + "，持仓金额： "+totalMoney + "，持仓均价： "+averagePriceBig.toPlainString());
				//持久化到数据库 
				HbTask task = new HbTask(taskId, null, totalAmount, totalMoney);
				this.taskService.updateTaskById(task, userId);
				
				//添加交易记录表
				long createTime = ordersDetail.getCreatedAt();
				Date date = new Date(createTime);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				BigDecimal fieldFeesBig = new BigDecimal(ordersDetail.getFieldFees()).setScale(moneyScale,BigDecimal.ROUND_DOWN);
				HbTrades trades = new HbTrades(taskId, symbol, loopCount,"1", "2", fieldAmountBig.toPlainString(), fieldMoneyBig.toPlainString(), ave.toPlainString(), fieldFeesBig.toPlainString(), sdf.format(date));
				this.tradesService.saveTrades(trades, userId);
			}else{
				send(userId, "【成交失败】撤消订单，重新下单");
				orderService.submitcancel(token, orderId);
			}
    }
    
    
    private void buy(BigDecimal totalMoneyBig,BigDecimal totalAmountBig,BigDecimal averagePriceBig){

			//达到购买要求，下单购买
			//获取购买数量
			String[] strs = JobUtil.getStrategyMoney(firstMoney, buyTradeLimit, moneyScale,buyMethod);
			String amount = strs[buyTradeCount];//购买金额
			BuyResult buyResult = this.orderService.createBuyOrderWithDetail(token, symbol, accountId, amount, moneyScale, amountScale);
			
			String state = buyResult.getState();
			if("filled".equals(state) || "partial-filled".equals(state)){
				
				BigDecimal fieldAmountBig = new BigDecimal(buyResult.getFieldAmount()).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
				BigDecimal fieldMoneybig = new BigDecimal(buyResult.getFieldMoney()).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
				
				if("filled".equals(state)){
					fieldMoneybig = new BigDecimal(amount);
				}
				//减去手续费
				BigDecimal fieldFeesBig = new BigDecimal(buyResult.getFieldFees()).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
				fieldAmountBig = fieldAmountBig.subtract(fieldFeesBig).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
				
				
				totalAmountBig = totalAmountBig.add(fieldAmountBig).setScale(amountScale, BigDecimal.ROUND_HALF_UP);
				totalMoneyBig = totalMoneyBig.add(fieldMoneybig).setScale(moneyScale, BigDecimal.ROUND_HALF_UP);
				
				totalAmount = totalAmountBig.toPlainString();
				totalMoney = totalMoneyBig.toPlainString();
				//计算成交均价
				averagePriceBig = totalMoneyBig.divide(totalAmountBig,moneyScale,BigDecimal.ROUND_DOWN);
				if("partial-filled".equals(state)){
					send(userId, "【部分成交】交易数量： "+fieldAmountBig.toPlainString() +"，交易金额： "+fieldMoneybig.toPlainString());
					send(userId, "撤消未完成的订单");
					orderService.submitcancel(token, buyResult.getOrderId());
				}else{
					send(userId, "【买进成功】交易数量： "+fieldAmountBig.toPlainString() +"，交易金额： "+fieldMoneybig.toPlainString());
				}
				buyTradeCount++; //购买次数 +1 ；
				uping = false;
				downing = false;
				maxPrice = "0.00";
				minPrice = "0.00";
				send(userId, "【仓位祥情】持仓数量： "+ totalAmount + "，持仓金额： "+totalMoney + "，持仓均价： "+averagePriceBig.toPlainString());
				
				HbTask task = new HbTask(taskId, buyTradeCount, totalAmount, totalMoney);
				this.taskService.updateTaskById(task, userId);
				
				//添加交易记录表
				//计算成交单价
				BigDecimal priceBig = fieldMoneybig.divide(fieldAmountBig,moneyScale,BigDecimal.ROUND_DOWN);
				HbTrades trades = new HbTrades(taskId, symbol, loopCount,"1", "1", fieldMoneybig.toPlainString(), fieldAmountBig.toPlainString(), priceBig.toPlainString(), fieldFeesBig.toPlainString(), buyResult.getCreatedAt());
				this.tradesService.saveTrades(trades, userId);
			}else{
				send(userId, "【买进失败】撤消订单，重新下单");
				orderService.submitcancel(token, buyResult.getOrderId());
			}
		
    }
    
    private void send(Long userId,String message){
	    messageService.sendConsoleMessage(userId, message);
    }
 
    
    

  
 
}

